<template>
  <div>
    <n-grid x-gap="6">
      <n-grid-item span="12">
        <n-spin :show="formatLoading">
          <n-card title="原文" >
            <template #header-extra>
              <n-space justify="end" style="margin-bottom: 5px">
                <n-button type="primary" size="small" @click="contentHandler">格式化</n-button>
                <n-button type="primary" size="small" @click="rewrite">改写</n-button>
              </n-space>
            </template>
            <n-input
                type="textarea"
                v-model:value="story.originalContent"
                style="height: 500px"
                :show-count=true
            >
            </n-input>
          </n-card>
        </n-spin>
      </n-grid-item>
      <n-grid-item span="12">
        <n-spin :show="rewriteLoading">
          <n-card title="改写文章" style="margin-bottom: 16px">
            <template #header-extra>
              <n-space justify="end" style="margin-bottom: 5px">
                <n-button type="primary" size="small" @click="sentenseBreak('content')">智能分段</n-button>
                <n-button type="warning" size="small" @click="boardByParagraph">保存并分镜</n-button>
              </n-space>
            </template>
            <n-input
                type="textarea"
                v-model:value="story.content"
                style="height: 500px"
                :show-count=true
            >
            </n-input>
          </n-card>
        </n-spin>
      </n-grid-item>
      <n-grid-item span="12">
        <n-card title="人物信息">
          <template #header-extra>
            <n-space justify="end" style="margin-bottom: 5px">
              <n-button type="warning" size="small" @click="characterNameExtract" :loading="nameExtractLoading">
                提取人物姓名
              </n-button>
              <n-button type="primary" size="small" @click="characterModal = true; resetFormData()">新增角色</n-button>
            </n-space>
          </template>
          <n-table striped>
            <thead>
            <tr>
              <th style="width: 120px">操作</th>
              <th>人物名称</th>
              <th>性别</th>
              <th>lora</th>
              <th>描述</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="character in characterList">
              <td>
                <n-button style="width: 50px;" type="warning" size="small" @click="deleteCharacter(character.id)">删除
                </n-button>
                <n-button style="width: 50px;margin-left: 5px" type="primary" size="small"
                          @click="editCharacter(character)">编辑
                </n-button>
              </td>
              <td>{{ character.characterName }}</td>
              <td>{{ character.characterGender == "0" ? '男' : character.characterGender == '1' ? '女' : '未知' }}</td>
              <td>{{ character.characterLora }}</td>
              <td>{{ character.characterDescription }}</td>
            </tr>
            </tbody>
          </n-table>
        </n-card>
      </n-grid-item>
      <n-grid-item span="12">
        <n-card title="文本总结">
          <template #header-extra>
            <n-space justify="end" style="margin-bottom: 5px">
              <n-button type="primary" size="small" @click="summaryContent" :loading="summaryLoading">总结文本
              </n-button>
            </n-space>
          </template>
          <n-input
              type="textarea"
              v-model:value="story.summary"
              style="height: 200px"
          >
          </n-input>
        </n-card>

      </n-grid-item>
    </n-grid>

    <n-modal
        v-model:show="characterModal"
        class="custom-card"
        style="width: 600px"
        preset="card"
        title="新增人物信息"
        size="huge"
        :bordered="false"
    >
      <n-form
          ref="formRef"
          label-placement="left"
          :label-width="80"
          :style="{
            maxWidth: '640px'
          }"
      >
        <n-form-item label="名称" path="characterName">
          <n-input v-model:value="characterForm.characterName" placeholder="人物名称"/>
        </n-form-item>
        <n-form-item label="gender" path="characterGender">
          <n-select :options="sexDict" v-model:value="characterForm.characterGender">
          </n-select>
        </n-form-item>

        <n-form-item label="人物描述" path="characterDescription">
          <n-input v-model:value="characterForm.characterDescription" type="textarea" style="height: 100px;"
                   placeholder="人物性别,形象,衣着描述">
          </n-input>
          <n-button type="primary" style="height: 100px; margin-left: 5px;" @click="promptTemplateShow = true">
            提示词器
          </n-button>
        </n-form-item>
        <n-form-item label="LoRA" path="characterLora">
          <n-input v-model:value="characterForm.characterLora" placeholder="人物使用的LoRA">
          </n-input>
          <n-button type="primary" style="margin-left: 5px;" @click="modelSelectorShow = true">模型选择</n-button>
        </n-form-item>
      </n-form>
      <n-space justify="end">
        <n-button type="primary" @click="addCharacter" :loading="addCharacterLoading">确定</n-button>
      </n-space>
    </n-modal>

    <n-drawer v-model:show="modelSelectorShow" :width="promptTemplateWidth">
      <n-drawer-content title="Lora模型选择器" closable>
        <ModelSelector modelType="lora" :story-id="props.storyId" @modelSelectEvent="modelSelectEvent"></ModelSelector>
      </n-drawer-content>
    </n-drawer>

    <n-drawer v-model:show="promptTemplateShow" :width="promptTemplateWidth">
      <n-drawer-content title="提示词生成器" closable>
        <PromptTemplate code="03" @loadPromptEvent="loadPromptEvent"></PromptTemplate>
      </n-drawer-content>
    </n-drawer>

  </div>
</template>
<script setup lang="ts">
import {useMessage} from 'naive-ui'
import {onMounted, reactive, ref} from "vue";
import {storyController} from '@/api/story/story.api'
import {storyBoardController} from "@/api/controller/story/storyBoard.api";
import {storyCharacterController} from '@/api/controller/story/storyCharacterController'
import {useStaticDict} from '@/dictionary/useStaticDict'
import ModelSelector from '@/components/paint/modelSelector/modelSelector.vue'
import PromptTemplate from '@/components/prompt/promptTemplate.vue'


const message = useMessage()
const story = ref(Object)
const formatLoading = ref(false)
const summaryLoading = ref(false)
const characterModal = ref(false)
const addCharacterLoading = ref(false)
const characterList = ref(null)
const {sexDict} = useStaticDict()
const nameExtractLoading = ref(false)
const promptTemplateShow = ref(false)
const modelSelectorShow = ref(false)
const promptTemplateWidth = ref(0)
const rewriteLoading = ref(false)

const props = defineProps({
  storyId: {
    type: String,
    required: true
  }
})


const characterForm = reactive({
  characterName: '',
  characterDescription: '',
  characterLora: '',
  chapterId: props.storyId,
  characterGender: '1',
  id: ''
})

const boardList = ref([])


onMounted(() => {
  getStory()
  getCharacterList()
  // 设置当前drawerWidth 宽度
  promptTemplateWidth.value = window.innerWidth - 300
  window.addEventListener('resize', handleResize);
})

// 窗口宽度变化
const handleResize = () => {
  promptTemplateWidth.value = window.innerWidth - 300;
}

// 按段分镜
const boardByParagraph = () => {
  formatLoading.value = true
  storyBoardController.boardByParagraph(story.value).then(res => {
    formatLoading.value = false
    if (res.code === 200) {
      boardList.value = res.data
    } else {
      message.error(res.msg)
    }
  }).catch(err => {
    formatLoading.value = false
  })
}


const modelSelectEvent = (modelObj: any) => {
  characterForm.characterLora = "<lora:" + modelObj.modelName + ":1>"
  modelSelectorShow.value = false
}


const loadPromptEvent = (prompt: string, negativePrompt: string) => {
  characterForm.characterDescription = prompt
  promptTemplateShow.value = false
}

// 重置表单
const resetFormData = () => {
  for (const key of Object.keys(characterForm)) {
    characterForm[key] = null; // 重置为默认值
  }
  characterForm.chapterId = props.storyId
}

const getStory = () => {
  storyController.getStoryById(props.storyId).then(res => {
    if (res.code === 200) {
      story.value = res.data.story
      boardList.value = res.data.sentences
    } else {
      message.error(res.msg)
    }
  })
}


const getCharacterList = () => {
  storyCharacterController.getCharacterList(props.storyId).then(res => {
    if (res.code === 200) {
      characterList.value = res.data
    }
  })
}


const contentHandler = () => {
  const text = story.value.originalContent
  // 分割文本为段落
  const paragraphs = text.split('\n').filter(paragraph => paragraph.trim() !== '');
  // 删除每段前面的空格
  const processedParagraphs = paragraphs.map(paragraph => paragraph.replace(/^\s+/, ''));
  // 重新组合段落为文本
  const processedText = processedParagraphs.join('\n');
  story.value.originalContent = processedText
}

const sentenseBreak = (type: string) => {
  const param = {
    sentense: story.value.content,
    breakLength: 15
  }
  if (type === 'originalContent') {
    param.sentense = story.value.originalContent
  }
  storyController.sentenseBreak(param).then(res => {
    if (res.code === 200) {
      message.success("分段成功!")
      story.value.content = res.data
    } else {
      message.error(res.msg)
    }
  })
}

const summaryContent = () => {
  summaryLoading.value = true
  storyController.summary(story.value).then(res => {
    summaryLoading.value = false
    if (res.code == 200) {
      story.value.summary = res.data
    }
  }).finally(() => {
    summaryLoading.value = false
  })
}


const addCharacter = () => {
  addCharacterLoading.value = true
  storyCharacterController.addCharacter(characterForm).then(res => {
    addCharacterLoading.value = false
    characterModal.value = false
    if (res.code === 200) {
      message.success("操作成功!")
      getCharacterList()
    }
  })
}


const deleteCharacter = (characterId: string) => {
  window.$dialog.error({
    title: "温馨提醒",
    content: "删除操作不可逆，是否继续？",
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: () => {
      storyCharacterController.deleteCharacter(characterId).then(res => {
        if (res.code === 200) {
          window.$message.success(res.msg)
          getCharacterList()
        }
      })
    }
  })
}

const editCharacter = (character: any) => {
  characterForm.characterName = character.characterName
  characterForm.characterDescription = character.characterDescription
  characterForm.characterLora = character.characterLora
  characterForm.characterGender = character.characterGender
  characterForm.id = character.id
  characterModal.value = true
}


const characterNameExtract = () => {
  nameExtractLoading.value = true
  storyCharacterController.characterNameExtract(story.value).then(res => {
    nameExtractLoading.value = false
    if (res.code === 200) {
      getCharacterList();
    } else {
      message.error(res.data)
    }
  }).finally(() => {
    nameExtractLoading.value = false
  })
}


const rewrite = async () => {
  if (story.value.originalContent.length > 0) {
    const lines = story.value.originalContent.split('\n')
    const result = []
    let currentLine = ''
    for (const line of lines) {
      if (currentLine.length + line.length <= 800) {
        currentLine += (currentLine ? ' ' : '') + line;
      } else {
        result.push(currentLine);
        currentLine = line;
      }
    }
    if (currentLine) {
      result.push(currentLine);
    }
    rewriteLoading.value = true
    story.value.content = ''
    for (let i = 0; i < result.length; i++) {
      const param = {
        content: result[i]
      }
      const data = await storyController.rewrite(param)
      if (data.code === 200) {
        story.value.content += data.data
      }
    }
    rewriteLoading.value = false
  } else {
    message.error("请先填写内容!")
  }
}

const nextStep = (callback: any) => {
  storyController.checkStorySetting(props.storyId).then(res => {
    if (res.code === 200) {
      callback(true)
    } else {
      message.error(res.data);
      callback(false)
    }
  })
}

defineExpose({
  nextStep
})
</script>
